package top.hmtools.services;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import top.hmtools.beans.ColumnsInfoBean;
import top.hmtools.common.ECurdType;
import top.hmtools.common.TableNameTools;
import top.hmtools.mapperUnit.IMapperUnitBase;
import top.hmtools.system.SystemInfoTools;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 生成 mapper.xml 的服务层类
 * @author HyboJ
 * 创建日期：2018-2-1下午8:41:07
 */
@Service
public class MapperXmlCreateService extends BaseService {

	private ApplicationContext applicationContext;

	/**
	 * 生成 mapper.xml字符串
	 * @return
	 * @throws IOException
	 * @throws TemplateException
	 */
	public String createMapperXml(String basePackage,String dbName,String tableName){
		StringWriter result = new StringWriter();
		
		//获取xml模板
		InputStream mapperTemplateIS = this.getClass().getClassLoader().getResourceAsStream("template/MapperTemplate.xml");
		InputStreamReader inputStreamReader = new InputStreamReader(mapperTemplateIS);
		
		//定义占位符欲替换的字符串
		StringBuffer sbDaoName = new StringBuffer(TableNameTools.getDaoName(basePackage, tableName));
		StringBuffer sbCommon = new StringBuffer();
		StringBuffer sbAdd = new StringBuffer();
		StringBuffer sbDel = new StringBuffer();
		StringBuffer sbUpdate = new StringBuffer();
		StringBuffer sbSelect = new StringBuffer();
		
		//获取所有表字段信息
		List<ColumnsInfoBean> allColumInfos = this.tablesInfoDao.getAllColumInfos(dbName, tableName);
		
		String[] mapperUnitNames = this.applicationContext.getBeanNamesForType(IMapperUnitBase.class);
		for(String unitName:mapperUnitNames){
			IMapperUnitBase mapperUnit = this.applicationContext.getBean(unitName,IMapperUnitBase.class);
			
			//增
			if(ECurdType.CREAT.equals(mapperUnit.getCurdType())){
				String content = mapperUnit.createContent(basePackage, null, allColumInfos.toArray(new ColumnsInfoBean[0]));
				sbAdd.append(content);
				sbAdd.append(SystemInfoTools.getOSLineSeparator());
				sbAdd.append(SystemInfoTools.getOSLineSeparator());
		        
			}
			
			//删
			if(ECurdType.DELATE.equals(mapperUnit.getCurdType())){
				String content = mapperUnit.createContent(basePackage, null, allColumInfos.toArray(new ColumnsInfoBean[0]));
				sbDel.append(content);
				sbDel.append(SystemInfoTools.getOSLineSeparator());
				sbDel.append(SystemInfoTools.getOSLineSeparator());
		        
			}
			
			//改
			if(ECurdType.UPDATE.equals(mapperUnit.getCurdType())){
				String content = mapperUnit.createContent(basePackage, null, allColumInfos.toArray(new ColumnsInfoBean[0]));
				sbUpdate.append(content);
				sbUpdate.append(SystemInfoTools.getOSLineSeparator());
				sbUpdate.append(SystemInfoTools.getOSLineSeparator());
		        
			}
			
			//查
			if(ECurdType.READ.equals(mapperUnit.getCurdType())){
				String content = mapperUnit.createContent(basePackage, null, allColumInfos.toArray(new ColumnsInfoBean[0]));
				sbSelect.append(content);
				sbSelect.append(SystemInfoTools.getOSLineSeparator());
				sbSelect.append(SystemInfoTools.getOSLineSeparator());
		        
			}
		}
		
		//使用freemarker替换模板中的占位符
		Map<String, String> map = new HashMap<String, String>();
		map.put("daoName", sbDaoName.toString());
		map.put("commons", sbCommon.toString());
		map.put("add", sbAdd.toString());
		map.put("del", sbDel.toString());
		map.put("update", sbUpdate.toString());
		map.put("seletct", sbSelect.toString());
		Template t;
		try {
			t = new Template("MapperTemplate", inputStreamReader,new Configuration());
			t.process(map, result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toString();
	}

	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}
}
